#include "wifidata.h"
#include <QDebug>
#include <QTextStream>

WiFiData::WiFiData(QObject *parent) : QObject(parent)
{
    qproc = NULL;

    qproc = new QProcess( this );
    qproc->setReadChannel( QProcess::StandardOutput );

    //QObject::connect( qproc, SIGNAL(readyReadStandardOutput()), this, SLOT(readMyStandartOutput()) );
    QObject::connect( qproc, SIGNAL(readyReadStandardError()), this, SLOT(readMyErrorOutput()) );
    //QObject::connect( qproc, SIGNAL(started()), SLOT(statusCh()) );
    QObject::connect( qproc, SIGNAL(finished(int)), SLOT(readMyStandartOutput(int)) );
    //QObject::connect( qproc, SIGNAL(stateChanged(QProcess::ProcessState)), SLOT(statusCh()) );
}

void WiFiData::requestWiFiData( const QString &iw_iface )
{
    Q_UNUSED( iw_iface );

    QProcess::execute("/sbin/ifconfig wlan0 up");

    QString strRun = "/sbin/iwlist " + iw_iface + " scanning";
    //QString strRun = "/sbin/iwlist scanning"; //Segmentation failt - разобраться
    qproc->start( strRun );
}

void WiFiData::readMyStandartOutput( int statusProcess )
{
    //qDebug() << "WiFiData::readMyStandartOutput(): " << statusProcess;
    if( statusProcess != 0 ) {
        emit dataError();
        return; //?
    }
    bool flDataExists = false;

    /* читаем вывод программы iwlist*/
    QByteArray baData = qproc->readAllStandardOutput();

    QTextStream ts( baData );

    QRegExp re_macaddr("(\\b*Address:\\s*)(\\w\\w:\\w\\w:\\w\\w:\\w\\w:\\w\\w:\\w\\w)");
    QRegExp re_channel("([Cc]hannel:\\s*)(\\d\\d?)");
    QRegExp re_frequency("([Ff]requency:\\s*)(\\d\\.\\d\\d?\\d?)(\\b+)");
    QRegExp re_level("([Qq]uality\\s*=\\s*)(\\d\\d)/(\\d\\d)(\\s+)(Signal\\s+level\\s*=-\\s*)(\\d\\d?\\d?)(\\b+)");
    QRegExp re_essid("(ESSID:\\s*\")(.+)(\")");

    QRegExp re_encrypt("([Ee]ncryption\\s*key:)(\\w+)");
    QRegExp re_wpa("(IE:\\s*WPA\\s*[Vv]ersion)");
    QRegExp re_wpa2("(IE:\\s*)(IEEE \\d\\d\\d.\\d\\w?\\w?)\\/(WPA2\\s*[Vv]ersion)");

    QList< Map >::iterator itr = listData.begin();
    while (itr != listData.end())
    {
        listData.erase(itr);
        itr++;
    }

    bool flNextLine = true;
    QString line;

    while ( !ts.atEnd() )
    {
        if( flNextLine ) line = ts.readLine();

        if( re_macaddr.indexIn(line) != -1 )
        {
            flDataExists = true;
            Map elementList;

            QString foreign_mac = re_macaddr.cap(2);
            elementList["mac"] = QVariant(foreign_mac);
            //qDebug() << "---------------------------";
            while( (!ts.atEnd()) /*&& (re_endCell.indexIn(line) == -1)*/ )
            {
                line = ts.readLine();

                if( re_macaddr.indexIn(line) != -1 ) {
                    flNextLine = false;
                    break;
                }

                flNextLine = true;

                if( re_channel.indexIn(line) != -1 ) {
                    //qDebug() << re_channel.capturedTexts();
                    QString ch = re_channel.cap(2);
                    //qDebug() << "channel:" << ch;
                    elementList["channel"] = QVariant(ch);
                    continue;
                }

                if( re_frequency.indexIn(line) != -1 ) {
                    //qDebug() << re_frequency.capturedTexts();
                    QString fr = re_frequency.cap(2);
                    //qDebug() << "frequency:" << fr;
                    elementList["frequency"] = QVariant(fr);
                    continue;
                }

                if( re_level.indexIn(line) != -1 ) {
                    //qDebug() << re_level.capturedTexts();
                    QString lvl = re_level.cap(6);

                    int lvl_cur = (re_level.cap(2)).toInt();
                    int lvl_max = (re_level.cap(3)).toInt();
                    float q = 0.0;
                    if( lvl_max != 0 ) {
                        q = (float)lvl_cur / (float) lvl_max;
                    }

                    //qDebug() << "level:" << lvl;
                    //qDebug() << "quality:" << q;
                    elementList["level"] = QVariant(lvl);
                    elementList["quality"] = QVariant( q );
                    continue;
                }

                if( re_essid.indexIn(line) != -1 ) {
                    //qDebug() << re_essid.capturedTexts();
                    QString essid = re_essid.cap(2);
                    //qDebug() << "essid:" << essid;
                    elementList["essid"] = QVariant(essid);
                    continue;
                }

                if( re_encrypt.indexIn(line) != -1 ) {
                    //qDebug() << re_encrypt.capturedTexts();
                    QString encrypt = re_encrypt.cap(2);
                    //qDebug() << "encrypt:" << encrypt;
                    if( encrypt == "on" )
                        elementList["encrypt"] = QVariant( true );
                    else/* if( encrypt == "off" )*/
                        elementList["encrypt"] = QVariant( false );
                    continue;
                }

                if( re_wpa.indexIn(line) != -1 ) {
                    //qDebug() << "wpa";
                    elementList["wpa"] = QVariant(true);
                    continue;
                }

                if( re_wpa2.indexIn(line) != -1 ) {
                    //qDebug() << re_wpa2.capturedTexts();
                    QString wpa2 = re_wpa2.cap(2);
                    //qDebug() << "wpa2:" << wpa2;
                    elementList["wpa2"] = QVariant(wpa2);
                    continue;
                }

            }

            bool ch = elementList.contains("channel");
            ch = ch && elementList.contains("frequency");
            ch = ch && elementList.contains("level");
            ch = ch && elementList.contains("quality");
            ch = ch && elementList.contains("essid");
            ch = ch && elementList.contains("encrypt");
            if( ch ) {
                listData.append( elementList );
            }
        }
        /**/
    }

    /* данные готовы для считывания */
    emit dataReady( flDataExists );
}

void WiFiData::readMyErrorOutput()
{
    QByteArray baData = qproc->readAllStandardError();
    qDebug() << baData.data();

    emit dataError();
}

void WiFiData::statusCh()
{
    if( qproc->state() == QProcess::NotRunning ) {
        qDebug() << "***Update is not running !";
    } else if( qproc->state() == QProcess::Starting ) {
        qDebug() << "***Update is starting, but the program has not yet been invoked.";
    } else if( qproc->state() == QProcess::Running ) {
        qDebug() << "***Update is not running !";
    }
}

